#pragma once

#include "backendsCommon/BackendRegistry.hpp"

#include <boost/program_options.hpp>
#include <string>
#include <vector>

struct ProgramOptions
{
    std::string modelPath;
    std::string imagePath;
    std::string modelOutputLabelsPath;
    std::vector<armnn::BackendId> computeDevice;
};

/** Parse and get program options from command line arguments
 *
 * @param[in] argc    Number of command line arguments
 * @param[in] argv    Array of command line arguments
 * @param[in] options Program options
 * @return Status
 */
int GetProgramOptions(int argc, char* argv[], ProgramOptions& options)
{
    namespace po = boost::program_options;
    std::vector<armnn::BackendId> defaultBackends = {armnn::Compute::CpuAcc, armnn::Compute::CpuRef};

    const std::string backendsMessage = "Which device to run layers on by default. Possible choices: "
        + armnn::BackendRegistryInstance().GetBackendIdsAsString();

    po::options_description desc("Options");

    desc.add_options()
        ("help,h", "Display help messages")
        ("model-path,m", po::value<std::string>(&options.modelPath)->required(), "Path to armnn format model file")
        ("model-output-labels,p", po::value<std::string>(&options.modelOutputLabelsPath)->required(),
         "Path to model output labels file.")
        ("compute,c", po::value<std::vector<armnn::BackendId>>(&options.computeDevice)->default_value(defaultBackends),
         backendsMessage.c_str());

    po::variables_map vm;
    try
    {
        po::store(po::parse_command_line(argc, argv, desc), vm);

        if (vm.count("help"))
        {
            std::cout << desc << std::endl;
            return EXIT_FAILURE;
        }
        po::notify(vm);
    }
    catch (po::error& e)
    {
        std::cerr << e.what() << std::endl << std::endl;
        std::cerr << desc << std::endl;
        return EXIT_FAILURE;
    }
    return 0;
}
